/**
 * @file PulseOximeterservice.h
 * @brief 
 * @author xuesong (wenshaoliu@foxmail.com)
 * @version 1.0
 * @date 2023-07-24
 * 
 * @copyright Copyright (c) 2023  by xuesong
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2023-07-24     <td>1.0     <td>xuesong   <td>内容
 * </table>
 */

#ifndef __PULSE_OXIMETER_SERVICE_H__
#define __PULSE_OXIMETER_SERVICE_H__

#ifdef __cplusplus
extern "C"
{
#endif

/*********************************************************************
 * INCLUDES
 */

/*********************************************************************
 * CONSTANTS
 */


// Pulse Oximeter Service UUID
#define PulseOximeterServiceUUID            0x1822 //0xFF00//
// Pulse Oximeter characteristic UUID
#define PLX_SpotCheckMeasurementUUID        0x2A5E //0xFF01//
#define PLX_ContinuousMeasurementUUID       0x2A5F
#define PLX_FeaturesUUID                    0x2A60
#define PLX_RecordAccessCP                  0x2A52

// Maximum length of heart rate measurement characteristic
#define PulseOximeter_MEAS_MAX             (ATT_MTU_SIZE -5)

// SpO2PR-Spot-Check Flags field  
typedef union {
      struct
      {
        unsigned char TimeStampPresent 		            : 1;    // Timestamp field is present      
        unsigned char MeasureStatusPresent 		        : 1;    // Measurement Status field is present        
        unsigned char DeviceAndSensorStatusPresent 		: 1;    // Device and Sensor Status field is present        
        unsigned char PulseAmplitudeIndexPresent   		: 1;    // Pulse Amplitude Index field is present        
        unsigned char DeviceClockNotSet            		: 1;    // Device Clock is Not Set        
      }flagBit;
      uint8_t flagByte;
  }SpO2SpotCheckFlag;
// PLX Continuous Measurement Flags field  
typedef union {
      struct
      {
        unsigned char FastFieldIsPresent 		          : 1;    // Timestamp field is present      
        unsigned char SlowFieldIsPresent 		          : 1;    // Measurement Status field is present        
        unsigned char MeasureStatusPresent 		        : 1;    // Measurement Status field is present        
        unsigned char DeviceAndSensorStatusPresent 		: 1;    // Device and Sensor Status field is present        
        unsigned char PulseAmplitudeIndexPresent   		: 1;    // Pulse Amplitude Index field is present              
      }flagBit;
      uint8_t flagByte;
  }SpO2ContinuousMeasureFlag;
// #define SpO2PR_FastFieldIsPresent             0x01
// #define SpO2PR_SlowFieldIsPresent             0x02
// #define C_MeasurementStatusFieldIsPresent     0x04
// #define C_DeviceAndSensorStatusFieldIsPresent 0x08
// #define C_PulseAmplitudeIndexFieldIsPresent   0x10
#pragma pack (1)
typedef struct PLX_Features_Value
{
	union {
        struct
        {
            unsigned char MeasurementStatusSupport 		              : 1;    // Measurement Status support is present
            unsigned char DeviceAndSensorStatusSupport 		          : 1;    // Device and Sensor Status support is present
            unsigned char MeasurementStorageforSpotCheckSupport 		: 1;    // Measurement Storage for Spot-check measurements is supported
            unsigned char TimestampforSpotCheckSupport 		          : 1;    // Timestamp for Spot-check measurements is supported
            unsigned char FastMetricSupport 		                    : 1;    // SpO2PR-Fast metric is supported
            unsigned char SlowMetricSupport 		                    : 1;    // SpO2PR-Slow metric is supported
            unsigned char PulseAmplitudeIndexFieldSupport 		      : 1;    // Pulse Amplitude Index field is supported
            unsigned char MultipleBondsSupport 		                  : 1;    // Multiple Bonds Supported
        }flagBit;
        uint16_t flagByte;
    }SupportedFeaturesFlag;
	union {
        struct
        {
            unsigned char ReservedForFutureUse     		              : 4;    // Reserved for Future Use
            unsigned char MeasurementOngoingBitSupported            : 1;    // Measurement Ongoing bit supported
            unsigned char EarlyEstimatedDataBitSupported         		: 1;    // Early Estimated Data bit supported
            unsigned char ValidatedDataBitSupported    		          : 1;    // Validated Data bit supported
            unsigned char FullyQualifiedDataBitSupported            : 1;    // Fully Qualified Data bit supported
            unsigned char DataFromMeasurementStorageBitSupported    : 1;    // Data from Measurement Storage bit supported
            unsigned char DataForDemonstrationBitSupported 		      : 1;    // Data for Demonstration bit supported
            unsigned char DataForTestingBitSupported                : 1;    // Data for Testing bit supported
            unsigned char CalibrationOngoingBitSupported            : 1;    // Calibration Ongoing bit supported
            unsigned char MeasurementUnavailableBitSupported        : 1;    // Measurement Unavailable bit supported
            unsigned char QuestionableMeasurDetectedBitSupported    : 1;    // Questionable Measurement Detected bit supported
            unsigned char InvalidMeasureDetectedBitSupported        : 1;    // Invalid Measurement Detected bit supported
        }flagBit;
        uint16_t flagByte;
    }MeasurementStatusFlag;
	union {
        struct
        {
            unsigned char ExtendedDisplayUpdateOngoing              : 1;    // Extended Display Update Ongoing bit supported
            unsigned char EquipmentMalfunctionDetected              : 1;    // Equipment Malfunction Detected bit supported
            unsigned char SignalProcessingIrregularityDetected   		: 1;    // Signal Processing Irregularity Detected bit supported
            unsigned char InadequateSignalDetected    		          : 1;    // Inadequate Signal Detected bit supported
            unsigned char PoorSignalDetected                        : 1;    // Poor Signal Detected bit supported
            unsigned char LowPerfusionDetected                      : 1;    // Low Perfusion Detected bit supported
            unsigned char ErraticSignalDetected 		                : 1;    // Erratic Signal Detected bit supported
            unsigned char NonpulsatileSignalDetected                : 1;    // Nonpulsatile Signal Detected bit supported
            unsigned char QuestionablePulseDetected                 : 1;    // Questionable Pulse Detected bit supported
            unsigned char SignalAnalysisOngoing                     : 1;    // Signal Analysis Ongoing bit supported
            unsigned char SensorInterferenceDetected                : 1;    // Sensor Interference Detected bit supported
            unsigned char SensorUnconnectedtoUser                   : 1;    // Sensor Unconnected to User bit supported
            unsigned char UnknownSensorConnected                    : 1;    // Unknown Sensor Connected bit supported
            unsigned char SensorDisplaced                           : 1;    // Sensor Displaced bit supported
            unsigned char SensorMalfunctioning                      : 1;    // Sensor Malfunctioning bit supported
            unsigned char SensorDisconnected                        : 1;    // Sensor Disconnected bit supported
            unsigned char ReservedforFuture                         : 8;    // Reserved for Future Use
        }flagBit;
        uint32_t flagByte;
    }DeviceAndSensorStatusFlag;
}PLX_Features_Value_t;
#pragma pack ()

typedef enum
{
  NaN = 0x07FF,       //not a unmber
  NRes = 0x0800,      //not at this resolution
  PMax = 0x07FE,      //pasitive max
  NMax = 0x0802,      //Negtive max
  NFuture = 0x0801,   //Reserved for future use
}SpecialShortValue;

// Callback events
#define HEARTRATE_MEAS_NOTI_ENABLED         1
#define HEARTRATE_MEAS_NOTI_DISABLED        2
#define HEARTRATE_COMMAND_SET               3

/*********************************************************************
 * TYPEDEFS
 */

// Pulse Oximeter Service callback function
typedef void (*PLXPServiceCB_t)(uint8 event);

/*********************************************************************
 * MACROS
 */

/*********************************************************************
 * Profile Callbacks
 */


/*********************************************************************
 * API FUNCTIONS 
 */
bStatus_t PulseOximeter_AddService( uint32_t services );

/**
 * @brief 
 * @param  pfnServiceCB     MyParamDoc
 */
void PulseOximeter_Register( PLXPServiceCB_t pfnServiceCB );

/**
 * @brief 
 * @param  param - Profile parameter ID
 * @param  len - length of data to right
 * @param  value - pointer to data to write.  This is dependent on
 *          the parameter ID and WILL be cast to the appropriate 
 *          data type (example: data type of uint16 will be cast to 
 *          uint16 pointer).
 * @return bStatus_t 
 */
extern bStatus_t PulseOximeter_SetParameter( uint8 param, uint8 len, void *value );
  
// /*
//  * HeartRate_GetParameter - Get a Heart Rate parameter.
//  *
//  *    param - Profile parameter ID
//  *    value - pointer to data to write.  This is dependent on
//  *          the parameter ID and WILL be cast to the appropriate 
//  *          data type (example: data type of uint16 will be cast to 
//  *          uint16 pointer).
//  */
extern bStatus_t PulseOximeter_GetParameter( uint8 param, void *value );

/*********************************************************************
 * @fn          HeartRate_MeasNotify
 *
 * @brief       Send a notification containing a heart rate
 *              measurement.
 *
 * @param       connHandle - connection handle
 * @param       pNoti - pointer to notification structure
 *
 * @return      Success or Failure
 */
extern bStatus_t PulseOximeter_ContiunusMeasNotify( uint16 connHandle, attHandleValueNoti_t *pNoti );


bStatus_t PulseOximeter_SpotCheckMeasIndicate( uint16 connHandle, attHandleValueInd_t *pInidicate );

/*********************************************************************
 * @fn          HeartRate_HandleConnStatusCB
 *
 * @brief       Heart Rate Service link status change handler function.
 *
 * @param       connHandle - connection handle
 * @param       changeType - type of change
 *
 * @return      none
 */
void PulseOximeter_HandleConnStatusCB( uint16 connHandle, uint8 changeType );

bStatus_t GAPRole_EncodeAdvService16bitUUID(uint8_t * pAdvData, uint8_t * pOffset, uint8_t maxSize, uint16_t uuid);

/*********************************************************************
*********************************************************************/

#ifdef __cplusplus
}
#endif

#endif /* HEARTRATESERVICE_H */
